package com.bungarus.group.service;

import com.bungarus.group.jdbc.GroupMemberManager;
import com.bungarus.group.model.Group;
import com.bungarus.group.model.GroupMember;
import com.bungarus.group.model.Member;
import com.bungarus.group.repo.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * Created by tang on 2018/12/13.
 */
@Service
public class MemberServiceImpl implements MemberService{
    private MemberRepository repository;
    private GroupMemberManager groupMemberManager;

    @Autowired
    public MemberServiceImpl(MemberRepository repository, GroupMemberManager groupMemberManager) {
        this.repository = repository;
        this.groupMemberManager = groupMemberManager;
    }

    @Override
    public Member isExists(String account, String pwd, long tid) {
        if(StringUtils.isEmpty(account) || StringUtils.isEmpty(pwd)
                || tid <= 0) {
            throw new IllegalArgumentException("member's account name or password cannot be empty.");
        }

        return this.repository.findByAccountNameAndPasswordAndTenantId(account, pwd, tid);
    }

    @Override
    public Member isExists(Member member) {
        if(null == member) {
            throw new IllegalArgumentException("member cannot be null.");
        }
        return isExists(member.getAccountName(), member.getPassword(), member.getTenantId());
    }

    @Override
    public Member createMember(long id, long tenantId, String account, String password) {
        return createMember(id, tenantId, MemberService.UNKNOWN, account, password);
    }

    @Override
    public Member createMember(long id, long tenantId, String name, String account, String password) {
        if(id <= 0 || tenantId <= 0
                || StringUtils.isEmpty(account)
                || StringUtils.isEmpty(password)) {
            throw new IllegalArgumentException("member's data is invalid.");
        }
        String _name = name;
        if(StringUtils.isEmpty(name)) {
            _name = MemberService.UNKNOWN;
        }
        Member member = Member.newBuilder()
                .id(id)
                .tenantId(tenantId)
                .pwd(password)
                .account(account)
                .name(_name)
                .build();

        return this.repository.save(member);
    }

    @Override
    public Member createMember(Member member) {
        if(null == member) {
            throw new IllegalArgumentException("input must not be null.");
        }
        return createMember(member.get_id(), member.getTenantId(),
                member.getName(), member.getAccountName(), member.getPassword());
    }

    @Override
    public void deleteMember(long id, long tenantId) {
        if(id <=0 || tenantId <= 0){
            throw new IllegalArgumentException("member's id and tenant id are invalid.");
        }
        Member member = Member.newBuilder()
                .id(id)
                .tenantId(tenantId).build();
        this.repository.deleteBy_idAndTenantId(id, tenantId);
        this.groupMemberManager.deleteMemberOfTenant(GroupMember.ofMember(member));
    }

    @Override
    public void deleteMember(Member member) {
        if(null == member) {
            throw new IllegalArgumentException("input cannot be null.");
        }
        deleteMember(member.get_id(), member.getTenantId());
    }

    @Override
    public List<Group> retrieveGroupsMemberBelongsTo(long mid, long tid) {
        return retrieveGroupsMemberBelongsTo(mid, tid, null);
    }

    @Override
    public List<Group> retrieveGroupsMemberBelongsTo(long mid, long tid, Pageable page) {
        if(mid <= 0 || tid <= 0) {
            throw new IllegalArgumentException("mid and tid are invalid.");
        }
        GroupMember gm = new GroupMember();
        gm.setMid(mid);
        gm.setTenantId(tid);

        Pageable _page = page;
        if(null == _page) {
            _page = PageRequest.of(DEFAULT_START_PAGE, DEFAULT_PAGE_SIZE, Sort.by(DEFAULT_SORT_BY_GROUP));
        }
        return this.groupMemberManager.findGroupsMemberBelongsTo(gm, _page);
    }

    @Override
    public List<Group> retrieveGroupsMemberBelongsTo(Member member) {
        return retrieveGroupsMemberBelongsTo(member, null);
    }

    @Override
    public List<Group> retrieveGroupsMemberBelongsTo(Member member, Pageable page) {
        if(null == member) {
            throw new IllegalArgumentException("member cannot be null.");
        }

        Pageable _page = page;
        if(null == _page) {
            _page = PageRequest.of(DEFAULT_START_PAGE, DEFAULT_PAGE_SIZE, Sort.by(DEFAULT_SORT_BY_GROUP));
        }
        return retrieveGroupsMemberBelongsTo(member.get_id(), member.getTenantId(), _page);
    }

    @Override
    public int totalCountOfGroupsMemberBelongsTo(long mid, long tid) {
        return this.groupMemberManager.totalCountOfGroupsMemberBelongsTo(mid, tid);
    }
}
